﻿var speed = 300;
var container;
var camera, scene, renderer;
var projector, plane;
var mouse2D, mouse3D, ray, rollOveredFace, isShiftDown = false,
    isCtrlDown = false;
var snakeBody = [];
var snakeBodyObj = [];
var gameOver = false;
var foodPositions = {
    x: -1,
    y: 24,
    z: -1
};
var direction = "down";
var lastDirection = "down";
var text;
var playText;
var mission = 1;
var currentMission = 1;
var objects = [];
var isMouseDown = false,
    onMouseDownPosition, radious = 1600,
    theta = 0,
    onMouseDownTheta = 45,
    phi = 60,
    onMouseDownPhi = 60;
var wall = [];
var stumblingBlock = [];

function initWall() {
    for (var i = 0; i < 20; i++) {
        var wallX = (i * 50) - 475;
        var wallZ = (i * 50) - 475;
        wall.push(new THREE.Vector3(wallX, 25, -475));
        wall.push(new THREE.Vector3(wallX, 25, 475));
        wall.push(new THREE.Vector3(-475, 25, wallZ));
        wall.push(new THREE.Vector3(475, 25, wallZ));
    }
    drawWall();
}
var stumblingBlockObj = [];

function addStumblingBlock() {
    for (var i = 0; i < stumblingBlock.length; i++) {
        var voxel = new THREE.Mesh(new THREE.CubeGeometry(50, 50, 50), [new THREE.MeshLambertMaterial({
            color: 0x8B8682,
            opacity: 1,
            shading: THREE.FlatShading
        }), new THREE.MeshFaceMaterial()]);
        voxel.position.x = stumblingBlock[i].x;
        voxel.position.y = 25;
        voxel.position.z = stumblingBlock[i].z;
        voxel.matrixAutoUpdate = false;
        voxel.updateMatrix();
        voxel.overdraw = true;
        scene.addObject(voxel);
        stumblingBlockObj.push(voxel);
    }
}
function drawStumblingBlock(ms) {
    if (scene) {
        for (var i = 0; i < stumblingBlockObj.length; i++) {
            scene.removeObject(stumblingBlockObj[i]);
        }
    }
    switch (ms) {
        case 1:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            break
        case 2:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 9 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 11 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 13 * 50 - 475
            });
            addStumblingBlock();
            break
        case 3:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 5 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 6 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 13 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 14 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 16 * 50 - 475
            });
            addStumblingBlock();
            break
        case 4:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 5 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 6 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 13 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 14 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 16 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 5 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 6 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 13 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 14 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 16 * 50 - 475
            });
            addStumblingBlock();
            break
        case 5:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 5 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 6 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 13 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 14 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 9 * 50 - 475,
                z: 16 * 50 - 475
            });
            stumblingBlock.push({
                x: 2 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 3 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 5 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 12 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 14 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 10 * 50 - 475
            });
            stumblingBlock.push({
                x: 16 * 50 - 475,
                z: 10 * 50 - 475
            });
            addStumblingBlock();
            break
        case 6:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 5 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 7 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 8 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 11 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 12 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 14 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 4 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 5 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 6 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 9 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 11 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 13 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 14 * 50 - 475
            });
            stumblingBlock.push({
                x: 4 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 5 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 6 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 7 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 8 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 9 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 11 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 12 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 13 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 14 * 50 - 475
            });
            stumblingBlock.push({
                x: 15 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 14 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 13 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 12 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 11 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 8 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 7 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 6 * 50 - 475,
                z: 15 * 50 - 475
            });
            stumblingBlock.push({
                x: 5 * 50 - 475,
                z: 15 * 50 - 475
            });
            addStumblingBlock();
            break
        case 7:
            stumblingBlockObj.length = 0;
            stumblingBlock.length = 0;
            for (var i = 0; i < 31; i++) {
                var xTemp = getRandomNumber(2, 17);
                var zTemp = getRandomNumber(2, 17);
                stumblingBlock.push({
                    x: xTemp * 50 - 475,
                    z: zTemp * 50 - 475
                });
            }
            addStumblingBlock();
            break
        default:
    }
}
function getRandomNumber(min, max) {
    return (min + Math.floor(Math.random() * (max - min + 1)));
}
function drawWall() {
    for (var i = 0; i < wall.length; i++) {
        var voxel = new THREE.Mesh(new THREE.CubeGeometry(50, 25, 50), [new THREE.MeshLambertMaterial({
            color: 0xEE9A49,
            opacity: 1,
            shading: THREE.FlatShading
        }), new THREE.MeshFaceMaterial()]);
        if ((wall[i].x == 475 && wall[i].z == 475) || (wall[i].x == -475 && wall[i].z == -475) || (wall[i].x == -475 && wall[i].z == 475) || (wall[i].x == 475 && wall[i].z == -475)) {
            voxel = new THREE.Mesh(new THREE.CubeGeometry(50, 50, 50), [new THREE.MeshLambertMaterial({
                color: 0xEE9A49,
                opacity: 1,
                shading: THREE.FlatShading
            }), new THREE.MeshFaceMaterial()]);
            voxel.position.x = wall[i].x;
            voxel.position.y = wall[i].y - 21;
            voxel.position.z = wall[i].z;
        } else {
            voxel.position.x = wall[i].x;
            voxel.position.y = wall[i].y - 33;
            voxel.position.z = wall[i].z;
        }
        voxel.matrixAutoUpdate = false;
        voxel.updateMatrix();
        voxel.overdraw = true;
        scene.addObject(voxel);
    }
}
function init() {
    container = document.createElement('div');
    document.body.appendChild(container);
    camera = new THREE.Camera(40, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.x = radious * Math.sin(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360);
    camera.position.y = radious * Math.sin(phi * Math.PI / 360);
    camera.position.y = 740;
    camera.position.x = 0;
    camera.position.z = radious * Math.cos(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360);
    camera.target.position.y = 100;
    scene = new THREE.Scene();
    onMouseDownPosition = new THREE.Vector2();
    var thePlayText = "PLAY";
    var theText = "3D Anakonda";
    var hash = document.location.hash.substr(1);
    if (hash.length !== 0) {
        theText = hash;
    }
    var playText3d = new THREE.TextGeometry(thePlayText, {
        size: 70,
        height: 30,
        curveSegments: 2,
        font: "helvetiker"
    });
    var text3d = new THREE.TextGeometry(theText, {
        size: 75,
        height: 20,
        curveSegments: 2,
        font: "helvetiker"
    });
    playText3d.computeBoundingBox();
    var playCenterOffset = -0.5 * (playText3d.boundingBox.x[1] - playText3d.boundingBox.x[0]);
    text3d.computeBoundingBox();
    var centerOffset = -0.5 * (text3d.boundingBox.x[1] - text3d.boundingBox.x[0]);
    var textMaterial = new THREE.MeshBasicMaterial({
        color: 0x008B00,
        wireframe: false
    });
    var playTextMaterial = new THREE.MeshBasicMaterial({
        color: 0x008B00,
        wireframe: false
    });
    playText = new THREE.Mesh(playText3d, playTextMaterial);
    text = new THREE.Mesh(text3d, textMaterial);
    playText.doubleSided = true;
    playText.position.x = -100;
    playText.position.y = 325;
    playText.position.z = 0;
    text.rotation.x = 0;
    text.rotation.y = Math.PI * 2;
    text.overdraw = true;
    text.doubleSided = true;
    text.position.x = centerOffset;
    text.position.y = 455;
    text.position.z = 0;
    text.rotation.x = 0;
    text.rotation.y = Math.PI * 2;
    text.overdraw = true;
    playParent = new THREE.Object3D();
    playParent.position.z = 500;
    playParent.addChild(playText);
    logoParent = new THREE.Object3D();
    logoParent.position.z = 500;
    logoParent.addChild(text);
    scene.addObject(logoParent);
    scene.addObject(playParent);
    objects.push(playText);
    objects.push(text);
    var geometry = new THREE.Geometry();
    geometry.vertices.push(new THREE.Vertex(new THREE.Vector3(-500, 0, 0)));
    geometry.vertices.push(new THREE.Vertex(new THREE.Vector3(500, 0, 0)));
    var material = new THREE.LineBasicMaterial({
        color: 0x000000,
        opacity: 0.2
    });
    for (var i = 0; i <= 20; i++) {
        var line = new THREE.Line(geometry, material);
        line.position.z = (i * 50) - 500;
        scene.addObject(line);
        var line = new THREE.Line(geometry, material);
        line.position.x = (i * 50) - 500;
        line.rotation.y = 90 * Math.PI / 180;
        scene.addObject(line);
    }
    projector = new THREE.Projector();
    plane = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000, 20, 20), new THREE.MeshFaceMaterial());
    plane.rotation.x = -90 * Math.PI / 180;
    scene.addObject(plane);
    mouse2D = new THREE.Vector3(0, 10000, 0.5);
    ray = new THREE.Ray(camera.position, null);
    renderer = new THREE.CanvasRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    container.appendChild(renderer.domElement);
    document.addEventListener('mouseup', onDocumentMouseUp, false);
    document.addEventListener('mousemove', onDocumentMouseMove, false);
    document.addEventListener('mousedown', onDocumentMouseDown, false);
    document.addEventListener('keydown', onDocumentKeyDown, false);
    document.addEventListener('keyup', onDocumentKeyUp, false);
    addAndRemoveLight();
    initWall();
}

function removeLight() {
    scene.lights.length = 0;
}
function addAndRemoveLight() {
    if (scene.lights.length == 0) {
        var ambientLight = new THREE.AmbientLight(0x555555);
        scene.addLight(ambientLight);
        var directionalLight = new THREE.DirectionalLight(0xffffff);
        directionalLight.position.x = -0.5;
        directionalLight.position.y = -0.5;
        directionalLight.position.z = 0.005;
        directionalLight.position.normalize();
        scene.addLight(directionalLight);
        var directionalLight = new THREE.DirectionalLight(0x808080);
        directionalLight.position.x = -0.1;
        directionalLight.position.y = 0.3;
        directionalLight.position.z = 0.5;
        directionalLight.position.normalize();
        scene.addLight(directionalLight);
    } else {
        scene.lights.length = 0;
    }
}
function addVoxel() {
    var sphereMaterial = new THREE.MeshNormalMaterial({
        color: 0x9400D3
    });
    var radius = snakeBody.length * 3,
        segments = 16,
        rings = 16;
    var sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), sphereMaterial);
    sphere.position.x = snakeBody[snakeBody.length - 1].x;
    sphere.position.y = snakeBody[snakeBody.length - 1].y;
    sphere.position.z = snakeBody[snakeBody.length - 1].z;
    if (sphere.position.x > -475 && sphere.position.x < 475 && sphere.position.z > -475 && sphere.position.z < 475) {
        scene.addObject(sphere);
    }
    snakeBodyObj.push(sphere);
}
function drawVoxel() {
    for (var i = 0; i < snakeBody.length; i++) {
        var sphereMaterial = new THREE.MeshNormalMaterial({
            color: 0x9400D3
        });
        var radius = snakeBody.length * 3,
            segments = 16,
            rings = 16;
        var sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), sphereMaterial);
        sphere.position.x = snakeBody[i].x;
        sphere.position.y = snakeBody[i].y;
        sphere.position.z = snakeBody[i].z;
        if (sphere.position.x > -475 && sphere.position.x < 475 && sphere.position.z > -475 && sphere.position.z < 475) {
            scene.addObject(sphere);
            snakeBodyObj.push(sphere);
        }
    }
}
function onDocumentKeyDown(event) {
    if (event.keyCode == 37 && lastDirection != "right") direction = "left";
    if (event.keyCode == 38 && lastDirection != "down") direction = "up";
    if (event.keyCode == 39 && lastDirection != "left") direction = "right";
    if (event.keyCode == 40 && lastDirection != "up") direction = "down";
    if (event.keyCode == 17) speed = 50;
    if (event.keyCode == 86) {
        btn_SetView_onclick();
    }
    if (event.keyCode == 76) {
        addAndRemoveLight();
    }
}
function onDocumentKeyUp(event) {
    if (event.keyCode == 16) {
        if (speed == 300) {
            speed = 50;
        } else {
            speed = 300;
        }
    }
    if (event.keyCode == 17) speed = 300;
    switch (event.keyCode) {
        case 16:
            isShiftDown = false;
            break;
        case 17:
            isCtrlDown = false;
            break;
    }
}
function render() {
    if (isShiftDown) {
        theta += mouse2D.x * 3;
    }
    mouse3D = projector.unprojectVector(mouse2D.clone(), camera);
    ray.direction = mouse3D.subSelf(camera.position).normalize();
    var intersects = ray.intersectScene(scene);
    if (intersects.length > 0) {
        if (intersects[0].face != rollOveredFace) {
            if (rollOveredFace) rollOveredFace.materials = [];
            rollOveredFace = intersects[0].face;
            rollOveredFace.materials = [new THREE.MeshBasicMaterial({
                color: 0xff0000,
                opacity: 0.5
            })];
        }
    } else if (rollOveredFace) {
        rollOveredFace.materials = [];
        rollOveredFace = null;
    }
    renderer.render(scene, camera);
}
function clearColor(point) {
    cxt.fillStyle = "#111";
    cxt.fillRect(point.x * width, point.y * height, height, width);
    var intersects = ray.intersectScene(scene);
    scene.removeObject(intersects[0].object);
}
function removeObjectByPosition(p) {
    var index = -1;
    if (scene) {
        for (var i = 0; i < scene.objects.length; i++) {
            if (scene.objects[i].position.x == p.x && scene.objects[i].position.y == p.y && scene.objects[i].position.z == p.z) {
                index = i;
            }
        }
        if (index != -1) {
            scene.removeObject(scene.objects[index]);
            snakeBodyObj.shift();
        }
    }
}
var foodObj = [];

function removeFood(p) {
    scene.removeObject(foodObj[0]);
}
var moveAsync = eval(Jscex.compile("async", function () {
    while (true) {
        $await(Jscex.Async.sleep(speed));
        if (snakeBody[snakeBody.length - 1].x < -425 || snakeBody[snakeBody.length - 1].x > 425 || snakeBody[snakeBody.length - 1].z < -425 || snakeBody[snakeBody.length - 1].z > 425) {
            gameOver = true;
        }
        if (snakeIsInSnake(snakeBody, {
            x: snakeBody[snakeBody.length - 1].x,
            z: snakeBody[snakeBody.length - 1].z
        })) {
            gameOver = true;
        }
        if (IsInSnake(stumblingBlock, {
            x: snakeBody[snakeBody.length - 1].x,
            z: snakeBody[snakeBody.length - 1].z
        })) {
            gameOver = true;
        }
        if (gameOver) {
            drawGameOver();
            break;
        }
        if (snakeBody.length > 16) {
            if (mission <= currentMission) mission++;
            drawMissionComplete();
            break;
        }
        drawFood(snakeBody);
        if (direction == "right") {
            if (lastDirection != "left") {
                lastDirection = "right";
                snakeBody.push(new THREE.Vector3(snakeBody[snakeBody.length - 1].x + 50, 25, snakeBody[snakeBody.length - 1].z));
                if (snakeBody[snakeBody.length - 1].x == foodPositions.x && snakeBody[snakeBody.length - 1].z == foodPositions.z) {
                    removeFood(foodPositions);
                    foodObj.shift();
                    foodPositions.x = -1;
                    foodPositions.z = -1;
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                } else {
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                    snakeBody.shift();
                }
            } else {
                direction = "left";
            }
        }
        if (direction == "left") {
            if (lastDirection != "right") {
                lastDirection = "left";
                snakeBody.push(new THREE.Vector3(snakeBody[snakeBody.length - 1].x - 50, 25, snakeBody[snakeBody.length - 1].z));
                if (snakeBody[snakeBody.length - 1].x == foodPositions.x && snakeBody[snakeBody.length - 1].z == foodPositions.z) {
                    removeFood(foodPositions);
                    foodObj.shift();
                    foodPositions.x = -1;
                    foodPositions.z = -1;
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                } else {
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                    snakeBody.shift();
                }
            } else {
                direction = "right";
            }
        }
        if (direction == "up") {
            if (lastDirection != "down") {
                lastDirection = "up";
                snakeBody.push(new THREE.Vector3(snakeBody[snakeBody.length - 1].x, 25, snakeBody[snakeBody.length - 1].z - 50));
                if (snakeBody[snakeBody.length - 1].x == foodPositions.x && snakeBody[snakeBody.length - 1].z == foodPositions.z) {
                    removeFood(foodPositions);
                    foodObj.shift();
                    foodPositions.x = -1;
                    foodPositions.z = -1;
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                } else {
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                    snakeBody.shift();
                }
            } else {
                direction = "down";
            }
        }
        if (direction == "down") {
            if (lastDirection != "up") {
                lastDirection = "down";
                snakeBody.push(new THREE.Vector3(snakeBody[snakeBody.length - 1].x, 25, snakeBody[snakeBody.length - 1].z + 50));
                if (snakeBody[snakeBody.length - 1].x == foodPositions.x && snakeBody[snakeBody.length - 1].z == foodPositions.z) {
                    removeFood(foodPositions);
                    foodObj.shift();
                    foodPositions.x = -1;
                    foodPositions.z = -1;
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                } else {
                    addVoxel();
                    removeObjectByPosition(snakeBody[0]);
                    snakeBody.shift();
                }
            } else {
                direction = "up";
            }
        }
    }
}));

function drawFood(p) {
    if (foodPositions.x == -1 && foodPositions.z == -1) {
        randomFoodPosition();
        var voxel = new THREE.Mesh(new THREE.CubeGeometry(50, 50, 50), [new THREE.MeshLambertMaterial({
            color: 0x7FFF00,
            opacity: 1,
            shading: THREE.FlatShading
        }), new THREE.MeshFaceMaterial()]);
        voxel.position.x = foodPositions.x;
        voxel.position.y = 25;
        voxel.position.z = foodPositions.z;
        voxel.matrixAutoUpdate = false;
        voxel.updateMatrix();
        voxel.overdraw = true;
        scene.addObject(voxel);
        foodObj.push(voxel);
    }
}
function randomFoodPosition() {
    foodPositions.x = (Math.random() * 18 + 1 | 0) * 50 - 475;
    foodPositions.y = 0;
    foodPositions.z = (Math.random() * 18 + 1 | 0) * 50 - 475;
    if (IsInSnake(snakeBody, foodPositions)) randomFoodPosition();
    if (IsInSnake(stumblingBlock, foodPositions)) randomFoodPosition();
}
function snakeIsInSnake(sb, p) {
    for (var i = 0; i < sb.length - 1; i++) {
        if (sb[i].x == p.x && sb[i].z == p.z) {
            return true;
        }
    }
    return false;
}
function IsInSnake(sb, p) {
    for (var i = 0; i < sb.length; i++) {
        if (sb[i].x == p.x && sb[i].z == p.z) {
            return true;
        }
    }
    return false;
}
var gameOverText;
var gameOverTextParent;
var completeTextParent;

function drawGameOver() {
    var gameText = "Game Over!";
    var text3d = new THREE.TextGeometry(gameText, {
        size: 80,
        height: 20,
        curveSegments: 2,
        font: "helvetiker"
    });
    text3d.computeBoundingBox();
    var centerOffset = -0.5 * (text3d.boundingBox.x[1] - text3d.boundingBox.x[0]);
    var textMaterial = new THREE.MeshBasicMaterial({
        color: Math.random() * 0xffffff,
        wireframe: false
    });
    gameOverText = new THREE.Mesh(text3d, textMaterial);
    gameOverText.doubleSided = false;
    gameOverText.position.x = centerOffset;
    gameOverText.position.y = 200;
    gameOverText.position.z = 0;
    gameOverText.rotation.x = 0;
    gameOverText.rotation.y = Math.PI * 2;
    gameOverText.overdraw = true;
    gameOverTextParent = new THREE.Object3D();
    gameOverTextParent.addChild(gameOverText);
    scene.addObject(gameOverTextParent);
    mouseOnBtnTag = 0;
    wordMoveBackAsync().start();
    logoMoveBackAsync().start();
}

function drawMissionComplete() {
    var completeText = "Mission Complete!";
    var text3d = new THREE.TextGeometry(completeText, {
        size: 80,
        height: 20,
        curveSegments: 2,
        font: "helvetiker"
    });
    text3d.computeBoundingBox();
    var centerOffset = -0.5 * (text3d.boundingBox.x[1] - text3d.boundingBox.x[0]);
    var textMaterial = new THREE.MeshBasicMaterial({
        color: Math.random() * 0xffffff,
        wireframe: false
    });
    completeOverText = new THREE.Mesh(text3d, textMaterial);
    completeOverText.doubleSided = false;
    completeOverText.position.x = centerOffset;
    completeOverText.position.y = 200;
    completeOverText.position.z = 0;
    completeOverText.rotation.x = 0;
    completeOverText.rotation.y = Math.PI * 2;
    completeOverText.overdraw = true;
    completeTextParent = new THREE.Object3D();
    completeTextParent.addChild(completeOverText);
    scene.addObject(completeTextParent);
    mouseOnBtnTag = 0;
    wordMoveBackAsync().start();
    logoMoveBackAsync().start();
}
init();
var wordMoveAsync = eval(Jscex.compile("async", function () {
    while (playParent.position.x > -500) {
        $await(Jscex.Async.sleep(1));
        playParent.position.x -= 30;
        render();
    }
}));
var logoMoveAsync = eval(Jscex.compile("async", function () {
    while (true) {
        $await(Jscex.Async.sleep(1));
        logoParent.position.z -= 30;
        if (logoParent.position.z < -450) {
            initSnakeBody();
            moveAsync().start();
            break;
        }
    }
}));
var wordMoveBackAsync = eval(Jscex.compile("async", function () {
    while (playParent.position.x < 0) {
        $await(Jscex.Async.sleep(1));
        playParent.position.x += 30;
        render();
    }
}));
var logoMoveBackAsync = eval(Jscex.compile("async", function () {
    while (true) {
        $await(Jscex.Async.sleep(1));
        logoParent.position.z += 30;
        if (logoParent.position.z > 300) {
            if (gameOverTextParent) {
                scene.removeChild(gameOverTextParent);
            }
            if (completeTextParent) {
                scene.removeChild(completeTextParent);
            }
            for (var i = 1; i < mission + 1; i++) {
                document.getElementById("Button" + i).disabled = "";
            }
            break;
        }
    }
}));

function onDocumentMouseDown(event) {
    event.preventDefault();
    isMouseDown = true;
    onMouseDownTheta = theta;
    onMouseDownPhi = phi;
    onMouseDownPosition.x = event.clientX;
    onMouseDownPosition.y = event.clientY;
    var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
    projector.unprojectVector(vector, camera);
    var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize());
    var intersects = ray.intersectObjects(objects);
    if (intersects.length > 0) {
        startGame(mission);
    }
}

function initSnakeBody() {
    for (var i = 0; i < snakeBodyObj.length; i++) {
        scene.removeObject(snakeBodyObj[i]);
    }
    gameOver = false;
    snakeBody.length = 0;
    snakeBodyObj.length = 0;
    direction = "right";
    lastDirection = "right";
    bodyPosition1 = new THREE.Vector3(-425, 25, -425);
    snakeBody.push(bodyPosition1);
    bodyPosition2 = new THREE.Vector3(-375, 25, -425);
    snakeBody.push(bodyPosition2);
    bodyPosition3 = new THREE.Vector3(-325, 25, -425);
    snakeBody.push(bodyPosition3);
    drawVoxel();
}
function startGame(ms) {
    drawStumblingBlock(ms);
    logoMoveAsync().start();
    wordMoveAsync().start();
}
var mouseOnBtnTag = 0;

function onDocumentMouseMove(event) {
    event.preventDefault();
    var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
    projector.unprojectVector(vector, camera);
    var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize());
    var intersects = ray.intersectObjects(objects);
    if (intersects.length > 0) {
        objects[0].materials[0].color.setHex(0x00EE00);
        if (objects[0].position.z < 100 && playParent.position.x == 0) {
            objects[0].position.z += 10;
        }
    } else {
        if (mouseOnBtnTag == 0) {
            objects[0].materials[0].color.setHex(0x008B00);
            if (objects[0].position.z > 0 && playParent.position.x == 0) {
                objects[0].position.z -= 10;
            }
        }
    }
    if (isMouseDown) {
        theta = -((event.clientX - onMouseDownPosition.x) * 0.5) + onMouseDownTheta;
        phi = ((event.clientY - onMouseDownPosition.y) * 0.5) + onMouseDownPhi;
        phi = Math.min(180, Math.max(0, phi));
        camera.position.x = radious * Math.sin(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360);
        camera.position.y = radious * Math.sin(phi * Math.PI / 360);
        camera.position.z = radious * Math.cos(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360);
        camera.updateMatrix();
    }
}
function onDocumentMouseUp(event) {
    event.preventDefault();
    isMouseDown = false;
}
var rotationLogoAsync = eval(Jscex.compile("async", function () {
    while (true) {
        $await(Jscex.Async.sleep(50));
        logoParent.rotation.y += 0.1;
        render();
    }
}));
rotationLogoAsync().start();

function btn_SetView_onclick() {
    camera.position.x = 9.2991709;
    camera.position.y = 1720;
    camera.position.z = 657.2601879002472;
    render();
}
function moveOnPlayBtn() {
    mouseOnBtnTag = 1;
    objects[0].materials[0].color.setHex(0x00EE00);
    if (objects[0].position.z < 100 && playParent.position.x == 0) {
        objects[0].position.z += 10;
    }
    render();
}
function moveOutPlayBtn() {
    mouseOnBtnTag = 0;
    objects[0].materials[0].color.setHex(0x008B00);
    if (objects[0].position.z > 0 && playParent.position.x == 0) {
        objects[0].position.z -= 10;
    }
    render();
}

function play_onclick(ms) {
    for (var i = 1; i < 8; i++) {
        document.getElementById("Button" + i).disabled = "disabled";
    }
    objects[0].materials[0].color.setHex(0x008B00);
    currentMission = ms;
    startGame(ms);
}
function speedup() {
    speed = 50;
}
function speeddown() {
    speed = 300;
}